package nc.bs.hihr.entrymng.bp;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.RuntimeEnv;
import nc.jdbc.framework.processor.ArrayListProcessor;
import nc.jdbc.framework.processor.ColumnListProcessor;
import nc.jdbc.framework.processor.MapProcessor;
import nc.message.Attachment;
import nc.message.pub.mobile.SMSAndMailUtil;
import nc.vo.pubapp.AppContext;
import nc.vo.pubapp.pattern.pub.SqlBuilder;

public class EmailBp {

	private BaseDAO dao;

	public void exec(String[] toMailPsnids, String[] tablePsnids) throws Exception {

		File file = new File(file());
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		// 禁用DTD验证和外部实体解析，以防止网络访问
		dbFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
		dbFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
		dbFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
		dbFactory.setXIncludeAware(false);
		dbFactory.setExpandEntityReferences(false);
		DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
		Document doc = dBuilder.parse(file);

		replaceTable(doc, tablePsnids);

		// 获取<body>元素
		Node bodyNode = doc.getElementsByTagName("body").item(0);
		// 转换<body>元素的内容为字符串
		String bodyContent = serializeNode(bodyNode);

		String subject = doc.getElementsByTagName("title").item(0).getTextContent();

		SqlBuilder sqlb = new SqlBuilder();
		sqlb.append("select email from bd_psndoc where email is not null and pk_psndoc", toMailPsnids);
		List<String> list = (List<String>) getDao().executeQuery(sqlb.toString(), new ColumnListProcessor());

		sqlb = new SqlBuilder();
		sqlb.append("select p.name as psnname, p.mobile as phone from bd_psndoc p inner join sm_user u on u.pk_base_doc=p.pk_psndoc where u.cuserid", AppContext.getInstance().getPkUser());
		Map<String, Object> map = (Map<String, Object>) getDao().executeQuery(sqlb.toString(), new MapProcessor());

		if(map != null) {
			bodyContent = bodyContent.replace("\n", "").replace("\r", "").replaceAll("\\{N\\}", String.valueOf(tablePsnids.length)).replaceAll("\\{psnname\\}", map.get("psnname") == null ? "" : map.get("psnname").toString()).replaceAll("\\{phone\\}", map.get("phone") == null ? "" : map.get("phone").toString());
		}

		if(list != null && list.size() > 0) {
			for(String email : list) {
				SMSAndMailUtil.sendHtmlEmail(new String[] { email }, subject, bodyContent, new Attachment[0]);
			}
		}
	}

	public void replaceTable(Document doc, String[] tablePsnids) throws Exception{
		// Extract data from the second row of the table
		NodeList rows = doc.getElementsByTagName("tr");
		Node secondRow = rows.item(1);
		NodeList cells = secondRow.getChildNodes();

		List<String> fieldNames = new ArrayList<>();
		List<String> fieldValues = new ArrayList<>();

		for (int i = 0; i < cells.getLength(); i++) {
			Node cell = cells.item(i);
			if (cell.getNodeType() == Node.ELEMENT_NODE) {
				fieldNames.add(cell.getTextContent().replace("{", "").replace("}", ""));
				fieldValues.add(cell.getTextContent());
			}
		}

		// Generate SQL query dynamically
		SqlBuilder queryBuilder = new SqlBuilder();
		queryBuilder.append("SELECT ");
		int len =  fieldNames.size();
		for(int i = 0; i < len; i++) {
			if(i == len - 1) {
				queryBuilder.append(fieldNames.get(i));
			}else {
				queryBuilder.append(fieldNames.get(i));
				queryBuilder.append(", ");
			}
		}
		queryBuilder.append(" FROM view_psn_offer WHERE pk_psndoc", tablePsnids);
		String query = queryBuilder.toString();

		// Query the database
		List<String[]> results = (List<String[]>) getDao().executeQuery(query, new ArrayListProcessor());

		// Replace second row in the table with results
		Element table = (Element) doc.getElementsByTagName("table").item(0);
		table.removeChild(secondRow);
		for (Object[] resultRow : results) {
			Element newRow = doc.createElement("tr");
			for (Object cellValue : resultRow) {
				Element newCell = doc.createElement("td");
				newCell.setTextContent(cellValue == null ? "" : cellValue.toString());
				newRow.appendChild(newCell);
			}
			table.appendChild(newRow);
		}


	}

	private static String serializeNode(Node node) {
		StringBuilder serializedContent = new StringBuilder();
		if (node.getNodeType() == Node.ELEMENT_NODE) {
			// Start element tag
			serializedContent.append("<").append(node.getNodeName());

			// Add attributes
			NamedNodeMap attributes = node.getAttributes();
			for (int i = 0; i < attributes.getLength(); i++) {
				Node attribute = attributes.item(i);
				serializedContent.append(" ").append(attribute.getNodeName()).append("=\"").append(attribute.getNodeValue()).append("\"");
			}
			serializedContent.append(">");

			// Add child nodes
			NodeList children = node.getChildNodes();
			for (int i = 0; i < children.getLength(); i++) {
				Node child = children.item(i);
				serializedContent.append(serializeNode(child));
			}

			// End element tag
			serializedContent.append("</").append(node.getNodeName()).append(">");
		} else if (node.getNodeType() == Node.TEXT_NODE) {
			// Text content
			serializedContent.append(node.getNodeValue());
		}
		// Other node types (COMMENT, CDATA_SECTION, etc.) can be handled here as needed
		return serializedContent.toString();
	}

	public BaseDAO getDao() {
		if(dao == null) {
			dao = new BaseDAO();
		}
		return dao;
	}

	public String file() {
		return RuntimeEnv.getInstance().getNCHome() + "/resources/hrhi/offer/template.html";
	}
}
